"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
// Arrray 类型
var list = [1, 2, 3];
var list_frist = [1, 2, 3];
console.log(list, list_frist);
// Enum类型 在枚举中
var Direction;
(function (Direction) {
    Direction["NORTH"] = "NORTH";
    Direction["SOUTH"] = "SOUTH";
    Direction["EAST"] = "EAST";
    Direction["WEST"] = "WEST";
})(Direction || (Direction = {}));
var dir = Direction.NORTH;
console.log(dir);
// Any（动态类型）
var notSure = 4;
notSure = 'maybe a string instead';
notSure = false;
var notFalse = 4;
// notFalse = 'maybe a string instead';   error : notFalse must be number
// Tuple元组 类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。比如,你可以定义一对值分别为string 和 number 类型的元组
var x;
x = ['17355479252', 12];
// x = ['男', 23] 不能将类型“number”分配给类型“string”。ts(2322)
console.log(x[0].substr(1));
console.log(x[0]);
// 当访问一个越界的元素,会使用联合类型替代: 着重考虑  TS的  编码规则
// Void 
// 在某种程度上来说, void 类型像是与any 类型相反的,它表示没有任何类型数据.当一个函数没有返回值的时候,你通常会见到其返回值类型是:void:
function warnUser() {
    console.log("this is my warning message");
}
warnUser();
function warnSelf() {
    console.log("this is my warnSelf message");
    return 2 + 3;
}
console.log(warnSelf());
// Null and Underfined
// TypeScript 里 ,underfined和null两者 各自有自己的类型分别叫做 undefined和null
var u = undefined;
var n = null;
// 默认情况下, null和undefined 是所有类型的子类型. 就是说  你可以把null 和 undefined 复制给 number 类型的变量. 然而, 当你指定了
// 
var someValue = "this is a TypeScript";
var strLength = someValue.length;
// "尖括号" 语法
var strLengthFrist = someValue.length;
// as 语法
var someValueSceond = "this is a Lorenzo";
var strLengthSceond = someValueSceond.length;
console.log(strLength);
console.log(strLengthFrist);
console.log(strLengthSceond);
var greet = function (message) {
    if (message instanceof Array) {
        var messages_1 = "";
        message.forEach(function (msg) {
            messages_1 += "" + msg;
        });
        console.log("Received messages ", messages_1);
    }
    else {
        console.log("Received message =", message);
    }
};
greet('semlinker');
greet(['Hello', 'Angular']);
var semlinker = {
    uersName: 'Lorenzo',
    age: 31,
};
console.log(semlinker);
var Studentker = {
    name: 'Lorenzo',
};
// 只读属性用于限制 只能在对象刚刚创建的时候修改其值。 ReadonlyArray<T> 类型, 它与Array<T> 相似 只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改了。
var a = [1, 2, 3, 4, 5];
var ro = a;
// ro[0] = 12; error
// ro[1] = 12; error
// ro[2] = 12; error
// ro[3] = 12; error
// ro[4] = 12; error
console.log(ro[1]);
// ro.push[5]; error
console.log(ro.length);
/**
 * TypeScipt Class
 * 在面向对象语言中,类是一种面向对象计算机变成语言的构造，是创建对象的蓝图，免俗了所创建的对象共同的属性和方法。
 * 在TypeScript中，我们可以通过class关键字来定义一个类。
 *  */
var Greeter = /** @class */ (function () {
    function Greeter(message) {
        // 构造函数 - 执行初始化操作
        this.greeting = message;
    }
    Greeter.getClassName = function () {
        // 静态方法
        return 'Class name is Greeter';
    };
    Greeter.prototype.greet = function () {
        // 成员方法
        return 'Hello, ' + this.greeting;
    };
    Greeter.cname = 'Greeter'; //静态属性
    return Greeter;
}());
var greeter = new Greeter("world");
console.log(greeter);
console.log(greeter.greet());
console.log(Greeter.getClassName());
//  TypeScrpt Accessors 在 TypeScript 中，我们可以通过getter 和 setter 方法来实现数据的封装和有效性校验，防止出现异常数据。
var passcode = "hello angular js";
var Employee = /** @class */ (function () {
    function Employee() {
    }
    Object.defineProperty(Employee.prototype, "fullName", {
        get: function () {
            return this._fullName;
        },
        set: function (newName) {
            if (passcode && passcode == "hello angular 5") {
                this._fullName = newName;
            }
            else {
                console.log("Error: Unauthorized update of employee!");
            }
        },
        enumerable: false,
        configurable: true
    });
    return Employee;
}());
var employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
    console.log(employee.fullName);
}
/**
 * TypeScript Inheritance
 * 继承(Inheritance) 是一种联结类与类的层次模型。指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能，
 * 并可以增加它自己的新功能的能力，继承是类与类或者接口与接口之间的最常见的关系;  继承是一种 is-a关系
 * */
var Animal = /** @class */ (function () {
    function Animal(theName) {
        this.name = theName;
    }
    Animal.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 0; }
        console.log(this.name + " move " + distanceInMeters);
    };
    return Animal;
}());
var Snake = /** @class */ (function (_super) {
    __extends(Snake, _super);
    function Snake(name) {
        return _super.call(this, name) || this;
    }
    Snake.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 5; }
        console.log("Slithering...");
        _super.prototype.move.call(this, distanceInMeters);
    };
    return Snake;
}(Animal));
var sam = new Snake('Sammy the Python');
sam.move();
/**
 * TypeScript Generics
 * 泛型（Generics） 允许同一个函数接收不同类型参数的一种模板。
 */
// interface GenericIdentityFn<T> {
//   (arg: T) : T
// }
var GenericIdentityFn = /** @class */ (function () {
    function GenericIdentityFn() {
    }
    return GenericIdentityFn;
}());
var myGenericNumber = new GenericIdentityFn();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
    return x + y;
};
